package com.lengxf.aPlugins.service;

import cn.hutool.core.util.ClassUtil;
import com.lengxf.aPlugins.bizType.*;
import com.lengxf.aPlugins.entity.*;
import com.lengxf.aPlugins.model.MetaDataModel;
import com.lengxf.aPlugins.model.ModelInterface;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class PointGenerateService {


    //生成一次后后续不要进行修改
    //EVENT_POINT_BUSINESS_TYPE表主键 与 EVENT_POINT_QUEUE_CONFIG表主键 使用一个即可
    private static Long bizId = 1000001L;

    //业务编码 code
    //生成一次后后续不要进行修改
    private static Long bizCode = 1000001L;

    /**
     * 新生成点位的时候 需要修改下边这三个参数
     */
    //分组 id
    private static Long groupId = 1000001L;

    //点位 id
    private static Long pointId = 1000001L;

    // 关联关系表 id
    private static Long relationId = 1000001L;

    //需要删除的id范围
    private static final Long DELETE_ID_MIN = 1000000L;
    private static final Long DELETE_ID_MAX = 2000000L;

    private boolean deleteFlag = false;

    public void generate(ModelInterface modelInterface) {
        List<EventPointBusinessTypeEntity> eventPointBusinessTypeEntityList = new ArrayList<>();
        List<EventPointQueueConfigEntity> eventPointQueueConfigEntityList = new ArrayList<>();
        List<EventPointConfigEntity> eventPointConfigEntityList = new ArrayList<>();
        List<EventPointGroupConfigEntity> eventPointGroupConfigEntityList = new ArrayList<>();
        List<EventPointGroupRelationEntity> eventPointGroupRelationEntityList = new ArrayList<>();

        String areaEn = modelInterface.getAreaEn();
        String area = modelInterface.getArea();
        List<MetaDataModel> infoList = modelInterface.getInfoList();
        List<BizEnums> haveBizList = infoList.stream()
                .map(MetaDataModel::getBizType)
                .distinct().toList();

        for (BizEnums bizEnums : BizEnums.values()) {
            if (!haveBizList.contains(bizEnums)) {
                continue;
            }
            // 业务表数据
            EventPointBusinessTypeEntity eventPointBusinessTypeEntity = new EventPointBusinessTypeEntity(area, bizEnums)
                    .setId(bizId).setCode(String.valueOf(bizCode));
            eventPointBusinessTypeEntityList.add(eventPointBusinessTypeEntity);

            //队列表数据
            EventPointQueueConfigEntity eventPointQueueConfigEntity = new EventPointQueueConfigEntity(bizId, areaEn, bizEnums);
            eventPointQueueConfigEntityList.add(eventPointQueueConfigEntity);

            List<MetaDataModel> collect = infoList.stream().filter(e -> e.getBizType() == bizEnums).toList();
            for (MetaDataModel metaDataModel : collect) {
                String queueName = metaDataModel.getQueueName();
                BizEnums bizType = metaDataModel.getBizType();
                String keoServerPrefix = metaDataModel.getKeoServerPrefix();
                BizInterface actBiz = bizType.getActBiz();
                if (actBiz == null) {
                    continue;
                }
                List<InteractionModel> interactionModelList = actBiz.getInteractionModelList();
                for (InteractionModel interactionModel : interactionModelList) {
                    //分组数据
                    EventPointGroupConfigEntity eventPointGroupConfigEntity = buildEventPointGroupConfigEntity(interactionModel, metaDataModel);
                    eventPointGroupConfigEntityList.add(eventPointGroupConfigEntity);

                    List<String> pointSub = interactionModel.getPointSub();
                    Long sort = 1L;
                    for (String substr : pointSub) {
                        //点位数据
                        EventPointConfigEntity eventPointConfigEntity = new EventPointConfigEntity();
                        eventPointConfigEntity.setId(pointId);
                        String identifier = "";
                        if (queueName != null) {
                            identifier = keoServerPrefix + "." + bizType.getKepServerBizCode() + "." + queueName + "." + substr;
                        } else {
                            identifier = keoServerPrefix + "." + bizType.getKepServerBizCode() + "." + substr;
                        }
                        eventPointConfigEntity.setIdentifier(identifier);
                        eventPointConfigEntity.setName(area);
                        eventPointConfigEntity.setConfigName(bizType.getPointConfigName());
                        eventPointConfigEntityList.add(eventPointConfigEntity);

                        //关联关系
                        EventPointGroupRelationEntity eventPointGroupRelationEntity = new EventPointGroupRelationEntity();
                        eventPointGroupRelationEntity.setId(relationId);
                        eventPointGroupRelationEntity.setGroupConfigId(groupId);
                        eventPointGroupRelationEntity.setBusinessTypeId(bizId);
                        eventPointGroupRelationEntity.setPointConfigId(pointId);
                        eventPointGroupRelationEntity.setSort(sort);
                        eventPointGroupRelationEntityList.add(eventPointGroupRelationEntity);

                        relationId++;
                        pointId++;
                        sort++;
                    }
                    groupId++;
                }
            }
            bizId++;
            bizCode++;
        }
        // 生成SQL 写入文件
        eventPointBusinessTypeEntityList.forEach(SqlGenerator::generate);
        eventPointQueueConfigEntityList.forEach(SqlGenerator::generate);
        eventPointConfigEntityList.forEach(SqlGenerator::generate);
        eventPointGroupConfigEntityList.forEach(SqlGenerator::generate);
        eventPointGroupRelationEntityList.forEach(SqlGenerator::generate);
        if (!deleteFlag) {
            getInstances(SqlGenerator.class).forEach(e -> e.generateDeleteSql(DELETE_ID_MIN, DELETE_ID_MAX));
            deleteFlag = true;
        }
    }

    private static <T> Set<T> getInstances(Class<T> supClass) {
        String aPackage = ClassUtil.getPackage(supClass);
        Set<Class<?>> classes = ClassUtil.scanPackage(aPackage);
        //要将 本身排除
        return classes.stream().filter(sonClass -> {
            boolean allAssignableFrom = ClassUtil.isAllAssignableFrom(new Class[]{supClass}, new Class[]{sonClass});
            return allAssignableFrom && sonClass != supClass;
        }).map(e -> {
            try {
                return (T) e.getConstructor().newInstance();
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }).collect(Collectors.toSet());
    }


    private static EventPointGroupConfigEntity buildEventPointGroupConfigEntity(InteractionModel interactionModel, MetaDataModel metaDataModel) {
        GroupSubTypeEnum groupSubType = interactionModel.getGroupSubType();
        GroupTypeEnum groupType = interactionModel.getGroupType();
        EventPointGroupConfigEntity eventPointGroupConfigEntity = new EventPointGroupConfigEntity();
        eventPointGroupConfigEntity.setId(groupId);
        String queueName = metaDataModel.getQueueName();
        if (queueName == null) {
            queueName = metaDataModel.getKeoServerPrefix() + "_" + metaDataModel.getBizType().getKepServerBizCode();
        }
        eventPointGroupConfigEntity.setName(queueName + "-" + groupSubType.getValue());
        eventPointGroupConfigEntity.setType(groupType.getValue());
        return eventPointGroupConfigEntity;
    }

}
